package com.youdianstar.app.support

import android.os.Build
import com.youdianstar.app.common.util.LanguageConfig
import com.youdianstar.app.common.util.LogUtil
import com.google.gson.GsonBuilder
import com.youdianstar.app.BuildConfig
import com.youdianstar.app.util.DataAppManager
import com.youdianstar.app.common.network.BaseNetworkApi
import com.youdianstar.app.common.util.ApiRequestContext
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okio.Buffer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.*


/**
 * File: NetworkApi
 * Author: 82149 Create: 2021/9/18 11:48
 * Changes (from 2021/9/18)
 * --------------------------------------------------
 * description: 重写api
 * ---------------------------------------------------
 *
 */
//双重校验锁式-单例
//val apiService: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
//    NetworkApi.INSTANCE.getApi(ApiService::class.java, ApiService.SERVER_URL)
//}
class NetworkApi : BaseNetworkApi(){
    companion object {
        val INSTANCE: NetworkApi by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            NetworkApi()
        }
    }

    /**
     * 实现重写父类的setRetrofitBuilder方法，
     * 在这里可以对Retrofit.Builder做任意操作，比如添加GSON解析器，protobuf等
     */
    override fun setRetrofitBuilder(builder: Retrofit.Builder): Retrofit.Builder {
        return builder.apply {
            addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
            //addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 抛弃Rxjava2
        }
    }

    /**
     * 实现重写父类的setHttpClientBuilder方法，
     * 在这里可以添加拦截器，可以对 OkHttpClient.Builder 做任意操作
     */
    override fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder {
        builder.let {
            try {
                //域名信任
//                it.hostnameVerifier(NetSocketFactory.createTrustHostnameVerifier())
                //设置证书信任 方法1 (测试)
//                it.sslSocketFactory(NetSocketFactory.createSSLSocketFactory(),NetSocketFactory.createTrustAllManager()[0])
                //创建证书管理器 方法2
//                try {
//                    val stream = NetSocketFactory.trustedCertificatesInputStream("app.cer")
//                    val trustManager = NetSocketFactory.trustManagerForCertificates(stream)
//                    val sslContext = SSLContext.getInstance("TLS")
//                    sslContext.init(null, arrayOf(trustManager), null)
//                    it.sslSocketFactory(sslContext.socketFactory,trustManager)
//                } catch (e: Exception) {
//                    e.printStackTrace()
//                }

                it.addInterceptor{ chain ->
                    val original = chain.request()
                    val language : String = LanguageConfig.instance.getLanguageCode().uppercase(Locale.ROOT)
                    val androidId = DataAppManager.instance.getPhoneId()
                    val request = original.newBuilder()
                        .header("os","android")
                        .header("osVersion",Build.VERSION.RELEASE)
                        .header("phoneModel", "${Build.BRAND} ${Build.MODEL}")
                        .header("deviceMac",androidId)
                        .header("appVersion", BuildConfig.VER_NAME)
                        .header("brezze-language",language)
                        .header("platform-id","1")
                        .header("token",DataAppManager.instance.getToken())
                        .header("Authorized-Token",DataAppManager.instance.getToken()) // 添加与前端一致的认证头部
                        .header("Accept", "application/json, text/javascript, */*; q=0.01") // 添加Accept头部
                        .header("Cache-Control", "no-cache") // 添加缓存控制
                        .header("X-Requested-With", "XMLHttpRequest") // 添加AJAX标识
                        .method(original.method, original.body)
                        .build()
                    
                    // 记录请求信息到上下文，用于异常处理时获取
                    var requestToProceed = request
                    try {
                        val url = request.url.toString()
                        val method = request.method
                        var requestBody: String? = null
                        
                        // 尝试读取请求体（仅用于日志，不影响请求）
                        request.body?.let { body ->
                            try {
                                val buffer = Buffer()
                                body.writeTo(buffer)
                                val bodyBytes = buffer.readByteString()
                                requestBody = bodyBytes.utf8()
                                // 重新创建请求体，因为已经读取过了
                                val newBody = RequestBody.create(body.contentType(), bodyBytes)
                                requestToProceed = request.newBuilder()
                                    .method(request.method, newBody)
                                    .build()
                            } catch (e: Exception) {
                                // 忽略读取请求体的错误，使用原始请求
                                requestToProceed = request
                            }
                        }
                        
                        // 提取 URL 参数（query parameters）
                        val queryParams = mutableMapOf<String, Any?>()
                        request.url.queryParameterNames.forEach { name ->
                            queryParams[name] = request.url.queryParameter(name)
                        }
                        
                        // 设置请求上下文
                        ApiRequestContext.setContext(
                            ApiRequestContext.RequestInfo(
                                url = url,
                                method = method,
                                params = if (queryParams.isNotEmpty()) queryParams else null,
                                requestBody = requestBody
                            )
                        )
                    } catch (e: Exception) {
                        // 忽略设置上下文的错误，不影响请求
                        LogUtil.e("Failed to set request context: ${e.message}")
                        requestToProceed = request
                    }
                    
                    LogUtil.d("----Net:"+request.headers)
                    chain.proceed(requestToProceed)
                }
            }catch (e:Exception){
                e.printStackTrace()
            }
        }
        return builder
    }

    /**最终构造请求的Client对象*/
    override fun getOkHttpClient(): OkHttpClient {
        return setHttpClientBuilder(getBaseClient()).build()
    }

}